<?php
/*
 * [JINYUN!] (C)2001-2099 Jinyunweb.com
 * This is NOT a freeware, use is subject to license terms
 * $Id: 2017-12-13 03:39:35 apple $
*/
namespace core;
defined('BY_JYA') or exit('error');
class account{
	protected $wechat = null;
	public function __construct($wechat_id=0){
		
		if(!$wechat_id){
			$wechat_id=$_SESSION['wechat_id'];
		}
		$this->uniacid=$_SESSION['uniacid'];
		if(!$wechat_id){
			$this->wechat=pdo_get('core_account_wechat',array('uniacid'=>$this->uniacid,'isdefault'=>1));
		}else{
			$this->wechat=pdo_get('core_account_wechat',array('id'=>$wechat_id));
		}
		if(empty($this->wechat)){
			$this->wechat=pdo_get('core_account_wechat',array('uniacid'=>$this->uniacid));
		}
		//没有添加公众号，也能访问，调用系统公众号
		if((empty($this->wechat) || ($this->wechat['is_open'] && empty($this->wechat['appid']))) && $_SESSION['auth_wxid']){
			$this->wechat=pdo_get('core_account_wechat',array('id'=>$_SESSION['auth_wxid']));
		}
		if(empty($this->wechat)){
			if($wechat_id){
				exi('找不到指定公众号','error');
			}else{
				if($_SESSION['this']=='manage'){
					exi('请先添加绑定公众号！','error','core/wechat.list/');
				}else{
					return false;
					exi('请先添加绑定公众号。','error');
				}
			}
		}
		if (!$this->wechat['is_open'] && empty($this->wechat['appid'])){
			exi('未填写公众号appid','error');
		}
		//如果公众号为普通模式添加，APPsecret为必填项
		if(!$this->wechat['is_open'] && !$this->wechat['appsecret']){
			exi('未填写公众号appsecret','error');
		}
		if($this->wechat['expire']<TIMESTAMP){
			$this->getAccessToken();
		}
	}
	public function getAuthorizer_accessToken(){
		if($this->wechat['expire'] > TIMESTAMP){
			return $this->wechat['access_token'];
		}
		//通过第三方开放平台获取令牌
		$access_token=model('core/open')->get_access_token(0,$this->wechat['id']);
		return $access_token;
	}
	public function getAccessToken(){//获取access_token
		global $_AR;
		if($this->wechat['expire']>TIMESTAMP){
			return $this->wechat['access_token'];
		}
		if(!$this->wechat['appsecret']){
			$authorizer_access_token=$this->getAuthorizer_accessToken();
			return $authorizer_access_token;
		}else{
			$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->wechat['appid']}&secret={$this->wechat['appsecret']}";
		}
		$content = cfc('http')->ihttp_request($url);
		if(is_error($content)){
			$authorizer_access_token=$this->getAuthorizer_accessToken();
			if($authorizer_access_token){
				return $authorizer_access_token;
			}else{
				exi('获取微信公众号授权失败, 请稍后重试！错误详情：'.$content['message'],'error');
			}
		}
		$token = @json_decode($content['content'], true);
		if(empty($token) || empty($token['access_token'])) {
			$authorizer_access_token=$this->getAuthorizer_accessToken();
			if($authorizer_access_token){
				return $authorizer_access_token;
			}else{
				exi('获取微信公众号授权失败, 请稍后重试！ 公众平台返回原始数据为: 错误代码-' . $token['errcode'] . '，错误信息-' . $token['errmsg'].'错误详情：'.$this->error_code($token['errcode']),'error');
			}
		}
		$record = array();
		$record['access_token'] = $token['access_token'];
		$record['expire'] = TIMESTAMP + $token['expires_in'] - 200;
		pdo_update('core_account_wechat',$record,array('id'=>$this->wechat['id']));
		$this->wechat['access_token']=$token['access_token'];
		return $token['access_token'];
	}
	//发起http请求
	public function request($url,$post=null,$continue=true,$direct=false,$return_error=false,$return_data=false){
		if($this->return_error_one){
			$return_error=true;
			$this->return_error_one=false;
		}
		if($this->return_error){
			$return_error=true;
		}
		$rurl=str_replace(array('{access_token}','ACCESS_TOKEN'),$this->wechat['access_token'],$url);
		if($post){
			$result=cfc('http')->ihttp_request($rurl,$post);
		}else{
			$result=cfc('http')->ihttp_get($rurl);
		}
		if(is_error($result)){
			$message="访问公众平台接口失败, 错误: {$result['message']}";
			if($return_error){
				return error($message);
			}else{
				exi($message,'error');
			}
		}
		$data=preg_replace('/[\x00-\x1F]/','',$result['content']);
		$data=@json_decode($data,true);
		if(($data['errcode']=='40001' || $data['errcode']=='42001') && $continue){
			$this->getAccessToken();
			$data=$this->request($url,$post,false,$direct,$return_error);
			return $data;
		}
		if($data['errcode']){
			if($return_data){
				return $data;
			}
			$message="访问微信接口错误, 错误代码: {$data['errcode']}, 错误信息: {$data['errmsg']},错误详情：{$this->error_code($data['errcode'])}";
			if($return_error || $_SESSION['this']=='custom'){
				return error($message);
			}else{
				exi($message,'error');
			}
		}
		if($direct){
			return $result;
		}
		if(!is_array($data) || !$data){
			$message='访问微信接口错误，以下为原始数据：'.$result['content'];
			if($return_error){
				return error($message);
			}else{
				exi($message,'error');
			}
		}
		return $data;
	}
	//给第三方插件提供的额外接口，用于获取access_token
	public function access_token(){
		return $this->getAccessToken();
	}
	//粉丝标签相关
	public function add_tag($title){
		//创建标签
		if(!$title || !is_string($title)){
			return error('参数错误！');
		}
		$url='https://api.weixin.qq.com/cgi-bin/tags/create?access_token={access_token}';
		$post=array('tag'=>array('name'=>$title));
		$post=ijson_encode($post);
		$result=$this->request($url,$post);
		return $result['tag']['id'];
	}
	public function get_tag(){
		//获取标签
		$url='https://api.weixin.qq.com/cgi-bin/tags/get?access_token={access_token}';
		$result=$this->request($url);
		return $result['tags'];
	}
	public function edit_tag($tag){
		//编辑标签
		if(!is_array($tag) || !$tag['id'] || !$tag['name']){
			return error('参数错误！');
		}
		$url='https://api.weixin.qq.com/cgi-bin/tags/update?access_token={access_token}';
		$tag=array_fields(array('id','name'),$tag);
		$post=array('tag'=>$tag);
		$post=ijson_encode($post);
		$res=$this->request($url,$post);
		return true;
	}
	public function del_tag($tag_id){
		if(!$tag_id){
			return error('参数错误！');
		}
		//删除标签
		$url='https://api.weixin.qq.com/cgi-bin/tags/delete?access_token={access_token}';
		$post=array('tag'=>array('id'=>$tag_id));
		$post=ijson_encode($post);
		$this->request($url,$post);
		return true;
	}
	public function use_tag($openids,$tag_id){
		//给用户打标签
		if(!$openids || !$tag_id){
			return error('参数错误！');
		}
		$url='https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token={access_token}';
		$post=array('tagid'=>$tag_id);
		if(!is_array($openids)){
			$openids=array($openids);
		}
		$post['openid_list']=$openids;
		$post=ijson_encode($post);
		$res=$this->request($url,$post);
		return true;
	}
	public function cancel_tag($openids,$tag_id){
		//给用户取消标签
		if(!$openids || !$tag_id){
			return error('参数错误！');
		}
		$url='https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token={access_token}';
		$post=array('tagid'=>$tag_id);
		if(!is_array($openids)){
			$openids=array($openids);
		}
		$post['openid_list']=$openids;
		$post=ijson_encode($post);
		$res=$this->request($url,$post);
		return true;
	}
	//新增临时素材
	public function upload_media($source,$type) {
		//参数说明：附件相对地址，素材类型
		$url='https://api.weixin.qq.com/cgi-bin/media/upload?access_token={access_token}&type='.$type;
		if(ATTACHMENT_TYPE){
			//远程附件
			$ext=strrchr($source,'.');
			$source=tomedia($source);
			$temp=ROOT_AT.random(30).$ext;
			copy($source,$temp);
		}else{
			$temp=ROOT_AT.$source;
		}
		$post=array('media'=>'@'.$temp);
		$res=$this->request($url,$post,'','',true);
		if(ATTACHMENT_TYPE){
			@unlink($temp);
		}
		return $res['media_id'];
	}
	public function upload_media2($source,$type) {
		//参数说明：附件相对地址，素材类型
		$url='https://api.weixin.qq.com/cgi-bin/media/upload?access_token={access_token}&type='.$type;	
		$temp=$source;
		$post=array('media'=>'@'.$temp);
		$res=$this->request($url,$post);
		if(ATTACHMENT_TYPE){
			@unlink($temp);
		}
		return $res['media_id'];
	}
	//新增永久素材，除图文素材外，返回素材ID  根据附件本地地址获取素材ID
	public function add_media($source,$type,$source_title='未设置',$title='视频标题',$introduction='视频描述') {
		//参数说明：附件相对地址，素材类型
		$types=array(
			'1'=>'image',
			'2'=>'voice',
			'3'=>'video',
		);
		//检测附件是否存在于素材，如果存在直接返回素材ID
		$check=pdo_getcolumn('core_media',array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'type'=>$type,'attachment'=>$source),'media_id');
		if($check){
			return $check;
		}
		$url='https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={access_token}&type='.$types[$type];
		$ext=strrchr($source,'.');		
		$ext=strtolower($ext);
		if(ATTACHMENT_TYPE){
			//远程附件
			$source=tomedia($source);
			$temp=ROOT_AT.random(30).$ext;
			copy($source,$temp);
		}else{
			$temp=ROOT_AT.$source;
		}
		//检测素材格式和大小是否合法
		$size=filesize($temp);
		switch($type){
			case 1:
				$yes=in_array($ext,array('.png','.peg','.jpg','.gif','.jpeg')) && $size<=2*1024*1024;
				break;
			case 2:
				$yes=in_array($ext,array('.amr','.mp3')) && $size<=2*1024*1024;
				break;
			case 3:
				$yes=in_array($ext,array('.mp4')) && $size<=10*1024*1024;
				break;
		}
		if(!$yes){
			return error('素材格式或者大小错误！'.$type.$ext.$size);
		}
		if($type==3){
			$post=array('media'=>'@'.$temp);
			$post['description']=ijson_encode(array('title'=>$title,'introduction'=>$introduction));
		}else{
			$post=array('media'=>'@'.$temp);
		}
		$res=$this->request($url,$post);
		if(ATTACHMENT_TYPE){
			@unlink($temp);
		}
		if(!$res['media_id']){
			return false;
		}
		//将素材入库
		$insert=array(
			'uniacid'=>$_SESSION['uniacid'],
			'wxgid'=>$this->wechat['id'],
			'type'=>$type,
			'createtime'=>TIMESTAMP,
			'attachment'=>$source,
			'content'=>$res['media_id'],
			'title'=>$source_title,
			'media_id'=>$res['media_id'],
			'url'=>$res['url'],
		);
		pdo_insert('core_media',$insert);
		return $res['media_id'];
	}
	//根据素材ID获取素材本地地址
	public function get_media_attachment($media_id='',$type='image',$url=''){
		if(!$media_id){
			$filename=$url;
		}else{
			$attachment=pdo_getcolumn('core_media',array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'media_id'=>$media_id),'attachment');
			if($attachment){
				return $attachment;
			}
			$api_url='https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={access_token}';
			$params=array(
				'media_id'=>$media_id,
			);
			$params=ijson_encode($params);
			
			switch($type){
				case 'image':
					//图片素材
					$response=$this->request($api_url,$params,true,true);
					
					$title =str_replace( array('attachment; filename=', '"',' '),'',$response['headers']['Content-disposition']);
					$ext=strrchr($title,'.');
					$ext=$ext?substr($ext,1):'';
					$filename = cfc('files')->source_save($response['content'],'image',$ext);
					break;
				case 'voice':
					//语音素材
					$response=$this->request($api_url,$params,true,true);
					$title =str_replace( array('attachment; filename=', '"',' '),'',$response['headers']['Content-disposition']);
					$ext=strrchr($title,'.');
					$ext=$ext?substr($ext,1):'';
					$filename = cfc('files')->source_save($response['content'],'audio',$ext);
					break;
				case 'video':
					//视频素材
					$response=$this->request($api_url,$params);
					if($response['down_url']){
						$ext=substr($response['down_url'], strrpos($response['down_url'], '=')+1);		
						$content=file_get_contents($response['down_url']);
						$title=$response['title'];
						$filename=cfc('files')->source_save($content,'video',$ext,'微信素材：'.$title);
						
					}else{
						exi('获取素材失败!');
					}
					break;
				default:
					exi('素材类型不合法！');
					break;
			}
		}
		/*$types=array(
			'image'=>1,
			'voice'=>2,
			'video'=>3,
		);
		$new_media=array(
			'uniacid'=>$_SESSION['uniacid'],
			'wxgid'=>$this->wechat['id'],
			'type'=>$types[$type],			
			'createtime'=>TIMESTAMP,
			'attachment'=>$filename,
			'media_id'=>$media_id,
			'url'=>$response['down_url'],
		);
		if($type=='video'){
			$new_media['title']=$title;
		}
		pdo_insert('core_media',$new_media);*/
		return $filename;
	}
	//获取素材列表
	public function get_medialist($type,$wxgid){
		$types=array(
			'1'=>'image',
			'2'=>'voice',
			'3'=>'video',
			'4'=>'news',
		);
		$api='https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token={access_token}';
		$result=$this->request($api);
		$type2=$types[$type];
		$num=$result[$type2.'_count'];
		$api='https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token={access_token}';
		for($i=0;$i<$num;$i=$i+20){
			$post=array(
				'type'=>$type2,
				'offset'=>$i,
				'count'=>20
			);
			$post=ijson_encode($post);
			$result=$this->request($api,$post);
			$medias=$result['item'];
			foreach($medias as $media){
				$id=pdo_getcolumn('core_media',array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$wxgid,'media_id'=>$media['media_id']),'id');
				if(!$id){
					if($media['url']){
						$gs=substr($media['url'], strrpos($media['url'], '=')+1);		
						$content=file_get_contents($media['url']);	
						$attachment=cfc('files')->source_save($content,$type2,$gs);
						$title=$media['name'];
					}else if($type == 2 || $type == 3){
						//音视频素材
						$title=$media['name'];
						$attachment=$this->get_media_attachment($media['media_id'],$type2,($media['cover_url']?$media['cover_url']:''));
						if($type == 3){
							$media['url'] = $media['vid'] ?$media['vid'] :'' ;
						}
					}else if($type == 4){
						//图文素材
						$title=$media['content']['news_item']['0']['title'];
						$attachment=$this->get_media_attachment($media['content']['news_item']['0']['thumb_media_id'],'image',$media['content']['news_item']['0']['thumb_url']);
						
					}
					$data=array(
						'uniacid'=>$_SESSION['uniacid'],
						'wxgid'=>$wxgid,
						'type'=>$type,
						'title'=>$title,
						'createtime'=>TIMESTAMP,
						'updatetime'=>$media['update_time'],
						'attachment'=>$attachment,
						'media_id'=>$media['media_id'],
						'url'=>$media['url']
					);
					pdo_insert('core_media',$data);
					if($type2=='news'){
						$id=pdo_insertid();
						foreach($media['content']['news_item'] as $index=>$article){
							$article['content']=str_replace('data-src=','src=',$article['content']);
							$insert=array(
								'uniacid'=>$_SESSION['uniacid'],
								'wxgid'=>$wxgid,
								'media_id'=>$id,
								'index'=>$index,
								'title'=>$article['title'],
								'thumb'=>$this->get_media_attachment($article['thumb_media_id'],'image',$article['thumb_url']),
								'show_cover_pic'=>$article['show_cover_pic'],
								'author'=>$article['author'],
								'digest'=>$article['digest'],
								'content'=>$article['content'],
								'url'=>$article['url'],
								'content_source_url'=>$article['content_source_url'],
							);
							pdo_insert('core_media_news',$insert);
						}
					}
				}
			}
		}
	}

	//上传图文消息内的图片获取URL【订阅号与服务号认证后均可用】
	public function add_media_news_image($source){
	    $api='https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={access_token}';
		$ext=strrchr($source,'.');
		$source=tomedia($source);
		$temp=ROOT_AT.random(30).$ext;
		copy($source,$temp);
	    $post=array('media'=>'@'.$temp);
	    $result=$this->request($api,$post);
		@unlink($temp);
		return $result['url'];
	}
	
	//上传图文消息素材【订阅号与服务号认证后均可用】
	public function add_media_news($articles,$source_title,$id=0){
	    $newsarticles=array();
		$num=0;
		//排序
		usort($articles,'paixu');
		foreach($articles as $article){
			if($num==8){
				//超过八篇的部分不予处理
				break;
			}
			$article=pdo_get('core_account_article',array('id'=>$article['id'],'uniacid'=>$_SESSION['uniacid']),array('id','title','pic_url','content','author'));
			if(!$article['pic_url'] || !$article['content'] || !$article['title']){
				exi('请先设置好文章的标题、封面、内容！','error','core/account.article/edit/id='.$article['id']);
			}
			$temp=array(
				'title'=>$article['title'],
				'thumb_media_id'=>$this->add_media($article['pic_url'],1),
				'show_cover_pic'=>true,
				'content_source_url'=>custom_url(array('core/article.article//id='.$article['id']),true),
			);
			if($article['author']){
				$temp['author']=$article['author'];
			}
				//文章内容整理
			preg_match_all('/src="([^"]+)"/',$article['content'],$matchs);
			if($matchs['1']){
					//如果有检测到图片，则替换之
				$search=array();$replace=array();
				foreach($matchs['1'] as $src){
					if(!in_array($src,$search)){
						$search[]=$src;
						$replace[]=$this->add_media_news_image($src);
						
					}
				}
				$temp['content']=str_replace($search,$replace,$article['content']);
			}else{
				$temp['content']=$article['content'];
			}
			$newsarticles[]=$temp;
			$num++;
		}
		$post=array('articles'=>$newsarticles);
		$old=pdo_get('core_media',array('id'=>$id,'uniacid'=>$_SESSION['uniacid']));
		if($old['media_id']){
			//更新素材！
			foreach($newsarticles as $k=>$cv){
				$data=array(
					'media_id'=>$old['media_id'],
					'index'=>$k,
					'articles'=>$cv,
				);
				$api='https://api.weixin.qq.com/cgi-bin/material/update_news?access_token={access_token}';		
				$result=$this->request($api,ijson_encode($data));
			}
			$update=array(
				'title'=>$source_title,
				'attachment'=>$articles['0']['pic_url']?:$articles['0']['image'],
				'lookcontent'=>ijson_encode($articles),
			);
			pdo_update('core_media',$update,array('id'=>$id));
			$media_id=$old['media_id'];
		}else{
			$api='https://api.weixin.qq.com/cgi-bin/material/add_news?access_token={access_token}';		
			$result=$this->request($api,ijson_encode($post));
			//将素材入库
			$insert=array(
				'uniacid'=>$_SESSION['uniacid'],
				'wxgid'=>$this->wechat['id'],
				'type'=>4,
				'createtime'=>TIMESTAMP,
				'title'=>$source_title,
				'attachment'=>$articles['0']['pic_url']?:$articles['0']['image'],
				'lookcontent'=>ijson_encode($articles),
				'media_id'=>$result['media_id'],
				'content'=>$result['media_id'],
			);
			pdo_insert('core_media',$insert);
			$id=pdo_insertid();
			$media_id=$result['media_id'];
		}
		return $media_id;
	}
	//TPL群发消息，接收群发任务ID，然后群发消息
	public function tplmass($id){
		$mass=pdo_get('core_mass',array('id'=>$id,'uniacid'=>$_SESSION['uniacid']));
		if(!$mass){
			exi('指定群发任务不存在！','error');
		}
		if($mass['content_type']!=0){
			exi('模板消息推送，只能发送文本消息！','error');
		}
		if(!$mass['template_id']){
			exi('该群发任务没有选择自定义模板！','error');
		}
		$tpl=pdo_get('core_account_tpl_template',array('id'=>$mass['template_id'],'uniacid'=>$_SESSION['uniacid']));
		$template_id=$this->get_tpl_template_id($tpl['template_name'],$tpl['title'],true);
		$content=array(
			'first'=>array('value'=>'',"color" => "#4a5077"),
			'keyword1'=>array('value'=>'',"color" => "#4a5077"),
			'remark'=>array('value'=>$mass['content'],"color" => "#4a5077"),
		);
		if($mass['saletask_type'] && $mass['saletask_type']!=4){
			//根据任务群发
			$this->getsaletask_mids($mass,$content,$template_id);
			return true;
		}elseif($mass['sendto_type']==1){
			//根据标签群发
			$params=array('uniacid'=>$_SESSION['uniacid'],'groupid'=>$mass['sendto']);
			$fans=pdo_getall('core_members',$params,'id');
			if(count($fans)==0){
				exi('当前群发对象里面没有任何用户！','error');
			}
			foreach($fans as $item){
				$item['openid']=pdo_getcolumn('core_fans',array('uniacid'=>$_SESSION['uniacid'],'mid'=>$item['id']),'openid');
				$this->sendTplNotice($item['openid'], $template_id, $content, '',true);
			}
		}else{
			//根据标签群发
			$params=array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id']);
			if($mass['sendto_type']!=3 && $mass['sendto']){
				$params['tagid_list like']='%;'.$mass['sendto'].';%';
			}
			$fans=pdo_getall('core_fans',$params,'openid');
			if(count($fans)==0){
				exi('当前群发对象里面没有任何用户！','error');
			}
			foreach($fans as $item){
				$this->sendTplNotice($item['openid'], $template_id, $content, '',true);
			}
		}
		//修改发送状态
		pdo_update('core_mass',array('status'=>1,'send_time'=>TIMESTAMP),array('id'=>$mass['id']));
		return true;
	}
	//群发消息，接收群发任务ID，然后群发消息
	public function mass($id,$iskefu=false){
		$mass=pdo_get('core_mass',array('id'=>$id,'uniacid'=>$_SESSION['uniacid']));
		if(!$mass){
			return error('指定群发任务不存在！');
		}
		$types=array(
			'0'=>'text',
			'1'=>'image',
			'2'=>'voice',
			'3'=>'mpvideo',
			'4'=>'mpnews',
		);
		$type=$types[$mass['content_type']];
		if($type=='text'){
			$content=array('content'=>$mass['content']);
		}elseif($type=='image'){
			$content=array('media_ids'=>$mass['content'],'recommend'=>$mass['title']);
		}elseif($type=='voice'){
			$content=array('media_id'=>$mass['content']);
		}elseif($type=='mpvideo'){
			$content=array('media_id'=>$mass['content']);
		}elseif($type=='mpnews'){
			$content=array('media_id'=>$mass['content']);
		}
		$post=array(
			$type=>$content,
			'msgtype'=>$type,
		);
		if($mass['saletask_type'] && $mass['saletask_type']!=4){
			//根据任务群发
			$this->getsaletask_mids($mass,$post);
			return true;
		}elseif($mass['sendto_type']==1){
			//根据标签群发
			$params=array('uniacid'=>$_SESSION['uniacid'],'groupid'=>$mass['sendto']);
			$fans=pdo_getall('core_members',$params,'id');
			if(count($fans)==0){
				exi('当前群发对象里面没有任何用户！','error');
			}
			foreach($fans as $item){
				$item['openid']=pdo_getcolumn('core_fans',array('uniacid'=>$_SESSION['uniacid'],'mid'=>$item['id']),'openid');
				$this->sendCustomNotice($post,$item['openid'],true);
			}
		}else{
			//根据标签群发
			if($iskefu){
				$params=array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id']);
				if($mass['sendto_type']!=3 && $mass['sendto']){
					$params['tagid_list like']='%;'.$mass['sendto'].';%';
				}
				$fans=pdo_getall('core_fans',$params,'openid');
				if(count($fans)==0){
					exi('当前群发对象里面没有任何用户！','error');
				}
				foreach($fans as $item){
					$this->sendCustomNotice($post,$item['openid'],true);
				}
			}else{
				$filter=array(
					'tag_id'=>$mass['sendto'],
					'is_to_all'=>($mass['sendto_type']==3)?true:false,
				);
				$post['filter']=$filter;
				$api='https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={access_token}';
			}
		}
		if(!$iskefu){
			$post=ijson_encode($post);
			$this->request($api,$post);
		}
		//修改发送状态
		pdo_update('core_mass',array('status'=>1,'send_time'=>TIMESTAMP),array('id'=>$mass['id']));
		return true;
	}
	
	//查询群发消息发送状态【订阅号与服务号认证后均可用】
	public function mass_status($msg_id){
	    $api='https://api.weixin.qq.com/cgi-bin/message/mass/get?access_token={access_token}';
	    $post=array('msg_id'=>$msg_id);//	群发消息后返回的消息id
	    $result=$this->request($api,$post);
	}
	//获取素材
	public function downloadMedia($media) {
		$mediatypes = array('image', 'voice', 'thumb');
		if (empty($media) || empty($media['media_id']) || (!empty($media['type']) && !in_array($media['type'], $mediatypes))) {
			return error('微信下载媒体资源参数错误');
		}
		$sendapi = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token={access_token}&media_id={$media['media_id']}";
		$response = $this->request($sendapi,'','',true);
		if(!empty($response['headers']['Content-disposition']) && strexists($response['headers']['Content-disposition'], $media['media_id'])){
			$filename =str_replace( array('attachment; filename=', '"',' '),'',$response['headers']['Content-disposition']);
			$ext=strrchr($filename,'.');
			$ext=$ext?substr($ext,1):'';
			$filename = cfc('files')->source_save($response['content'],'image',$ext,$filename);
			return $filename;
		} else {
			$response = json_decode($response['content'], true);
			return error($response['errmsg']);
		}
	}

	public function openidlist($part=1,$next_openid='') {
		//同步粉丝openid
		$api='https://api.weixin.qq.com/cgi-bin/user/get?access_token={access_token}&next_openid='.$next_openid;
		$result=$this->request($api);
		//unset($result['data']);print_r($result);exit;
		foreach($result['data']['openid'] as $openid){
			$check=pdo_getcolumn('core_fans',array('openid'=>$openid,'uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'type'=>2),'id');
			if(!$check){
				$insert=array(
					'uniacid'=>$_SESSION['uniacid'],
					'wxgid'=>$this->wechat['id'],
					'type'=>2,
					'openid'=>$openid,
					'createtime'=>TIMESTAMP,
					'updatetime'=>TIMESTAMP,
				);
				pdo_insert('core_fans',$insert);
			}else{
				pdo_update('core_fans',array('updatetime'=>TIMESTAMP),array('id'=>$check));
			}
		}
		if($result['total']>10000 && $part*10000<$result['total']){
			//粉丝数超过10000且尚未拉取完，继续拉取
			$part++;
			return $this->openidlist($part,$result['next_openid']);
		}
		//删除无效粉丝
		pdo_delete('core_fans',array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'type'=>2,'updatetime <'=>TIMESTAMP));
		return $result['total'];
	}
	public function getfanslist($page=1){
		//获取粉丝信息，每次获取1000条
		$fans=pdo_getslice('core_fans',array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'type'=>2),array($page,1000),$total,array('openid'));
		$count=count($fans);
		for($i=0;$i<$count;$i+=100){
			$openids=array_slice($fans,$i,100);
			foreach($openids as $key=>$row){
				if(!$row['openid']){
					unset($openids[$key]);
				}
			}
			$post=array('user_list'=>$openids);
			$post=ijson_encode($post);
			$api='https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token={access_token}';
			$result=$this->request($api,$post);
			foreach($result['user_info_list'] as $info){
				$data=array(
					'follow'=>$info['subscribe'],
					'tagid_list'=>($info['tagid_list'] && is_array($info['tagid_list']))?';'.@implode(';'.$info['tagid_list']).';':'',
					'nickname'=>str_replace("'",'',$info['nickname']),
					'sex'=>$info['sex'],
					'avatar'=>$info['headimgurl'],
					'updatetime'=>$info['subscribe_time'],
					'pcd'=>$info['country'].$info['province'].$info['city'],
				);
				if($info['unionid']){
					$data['unionid']=$info['unionid'];
				}
				pdo_update('core_fans',$data,array('openid'=>$info['openid'],'uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'type'=>2));
				$mid=pdo_getcolumn('core_fans',array('openid'=>$info['openid'],'uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'type'=>2),'mid');
				if($mid && $data['avatar'] && $data['nickname']){
					$upmember=array('avatar'=>$data['avatar'],'nickname'=>$data['nickname']);
					pdo_update('core_members',$upmember,array('uniacid'=>$_SESSION['uniacid'],'id'=>$mid));
				}
			}
		}
		return true;
	}
	public function getfans($openid) {//获取粉丝信息（已关注且存在交互的粉丝）
		$url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={access_token}&openid={$openid}&lang=zh_CN";
		return $this->request($url,array());
	}
	public function get_media($mediaid){
		$url='https://api.weixin.qq.com/cgi-bin/media/get?access_token='.$this->wechat['access_token'].'&media_id='.$mediaid;
		return $url;
	}
	public function get_openid_by_mid($mid,$isexi=false,$wxgid=''){
		$wxgid=$wxgid?:$this->wechat['id'];
		$openid=pdo_getcolumn('core_fans',array('mid'=>$mid,'wxgid'=>$wxgid),'openid');
		if(!$openid){
			$openid=pdo_getcolumn('core_fans',array('mid'=>$mid,'uniacid'=>$_SESSION['uniacid']),'openid');
			if(!$openid){
				if($isexi){
					exi('获取用户openid失败，用户未关注该公众号！','error');
				}else{
					return error('获取用户openid失败，用户未关注该公众号！');
				}
			}else{
				return $openid;
			}
		}
		return $openid;
	}
	//发送客服消息，结合多公众号机制，优先发送给主公众号对应粉丝。主公众号无相应粉丝，则发送给粉丝关注的公众号
	public function sendCustomNotice($data,$mid='',$isexi=false){
		global $_AR;
		if(empty($data)) {
			exi('发送客服消息,参数错误!','error');
		}
		if(empty($data['touser'])){
			if(!$mid){
				if($_SESSION['uid']){
					$mid=$_SESSION['uid'];
				}else{
					exi('发送客服消息时出现错误，未设置消息接收者！','error');
				}				
			}
			$openid=$this->get_openid_by_mid($mid);
			if(is_error($openid)){
				return $openid;
			}
			$data['touser']=$openid;
		}
		if($data['msgtype']=='news'){
			if(!$data['news']['articles']){
				$data['news']=array('articles'=>$data['news']);
			}
			foreach($data['news']['articles'] as &$news){
				$news['picurl']=tomedia($news['picurl'],true);
				$news['url']=custom_url($news['url'],true);
			}
			
		}
		$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={access_token}";
		$data=ijson_encode($data);
		$noexi=$isexi?false:true;
		$this->request($url,$data,true,false,$noexi);
		return true;
	}
	public function send_news($news,$mid=''){
		$data=array(
			'msgtype'=>'news',
			'news'=>array('articles'=>array($news)),
		);
		if(!$mid){
			$data['touser']=$_SESSION['openid'];
		}
		return $this->sendCustomNotice($data,$mid);
	}
	public function send_text($text,$mid=''){
		$data=array(
			'msgtype'=>'text',
			'text'=>array('content'=>$text),
		);
		if(!$mid){
			$data['touser']=$_SESSION['openid'];
		}
		return $this->sendCustomNotice($data,$mid);
	}
	//发送文本消息
	function sendText($content,$mid)
    {
        $send['msgtype'] = 'text';
        $send['text'] = array('content' => $content);
        $data = $this->sendCustomNotice($send,$mid);
        return $data;
    }
	//判断发送两个模板
	public function sendtwoNotice($openid_mid, $template_id, $postdata, $url = '',$msg_name='',$plugin_name='core',$itemid=0) {
		if($template_id){
			$this->checktplNotice($openid_mid, $template_id, $postdata, $url, $msg_name,$plugin_name,$itemid);
		}else{
			$this->checkCustomNotice($postdata,$openid_mid,$url,$msg_name,$plugin_name,$itemid);
		}
	}
	//整理推送模板消息
	public function checktplNotice($openid_mid, $template_id, $content=array(), $url='',$msg_name='',$plugin_name='core',$itemid=0){
		$tplmsg=$this->check_tpl_msg($msg_name,$plugin_name);
		if(!$tplmsg){
			return false;
		}
		if($tplmsg && $tplmsg!=1 && $itemid && class_exists(model($plugin_name.'/notice')) && method_exists(model($plugin_name.'/notice'),'gettpl_data')){
			$datas=model($plugin_name.'/notice')->gettpl_data($itemid);
			$tplmsg['keywords']=json_decode($tplmsg['keywords'],true);
			$content['first']=cfc('account')->replaceTemplate($tplmsg['first'],$datas);
			foreach ($tplmsg['keywords'] as $key => $value){
				$content['keyword'.$key+1]=cfc('account')->replaceTemplate($value,$datas);
			}
			$content['remark']=cfc('account')->replaceTemplate($tplmsg['footer'],$datas);
		}
		$this->sendTplNotice($openid_mid, $template_id, $content, $url);
	}
	//整理推送客服消息
	public function checkCustomNotice($msg, $mid='', $url='',$msg_name='',$plugin_name='core',$itemid=0){
		$kefumsg=$this->check_tpl_kefumsg($msg_name,$plugin_name);
		if(!$kefumsg){
			return false;
		}
		if($itemid && class_exists(model($plugin_name.'/notice')) && method_exists(model($plugin_name.'/notice'),'gettpl_data')){
			$datas=model($plugin_name.'/notice')->gettpl_data($itemid);
			$content=$kefumsg['kefumsg'];
			$content=cfc('account')->replaceTemplate($content,$datas);
		}else{
			$content = '';
			if (is_array($msg)) {
				$kefumsg['keywords']=json_decode($kefumsg['keywords'],true);
				$index=0;
				foreach ($msg as $key => $value){
					if (!(empty($value['title']))) 
					{
						$content .= $value['title'] . ':' . $value['value'] . "\n";
					}else{	
						if ($key == 'first' || $key == 'remark') {
							$content .= $value['value']."\n";
						}else{
							$content .= $kefumsg['keywords'][$index]['title'] . ':' . $value['value'] . "\n";
							$index++;
						}
					}
					
				}
			}else {
				$content = $msg;
			}
		}
		if (!(empty($url))) {
			$content .= '<a href=\'' . $url . '\'>点击查看详情</a>';
		}
		$senddata['msgtype'] = 'text';
		$senddata['text']['content'] = $content;
		return $this->sendCustomNotice($senddata,$mid);
	}
	//替换关键词
	public function replaceTemplate($str, $datas = array())
	{
		foreach ($datas as $d ) {
			$str = str_replace('[' . $d['name'] . ']', $d['value'], $str);
		}

		return $str;
	}
	//获取客服信息
	public function custom_info(){
	     $url='https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token={access_token}';
	     $return=$this->request($url);
	     return $return;
	}
	//查询在线客服
	public function custom_online(){
	     $url='https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist?access_token={access_token}';
	      $return=$this->request($url);
	     return $return;
	}
	//添加客服账号
	public function custom_add($kf_account,$nickname){
	     $post=array(
	        'kf_account'=>$kf_account, //完整客服帐号，格式为：帐号前缀@公众号微信号
	        'nickname'=>$nickname //客服昵称，最长16个字
	         );
	     $url='https://api.weixin.qq.com/customservice/kfaccount/add?access_token={access_token}';
	     $return=$this->request($url,ijson_encode($post));
	         exi('添加成功','error');
	}
	//邀请绑定客服帐号
	public function custom_invite($kf_account,$invite_wx){
	     $post=array(
	        'kf_account'=>$kf_account, //完整客服帐号，格式为：帐号前缀@公众号微信号
	        'invite_wx'=>$invite_wx //接收绑定邀请的客服微信号
	         );
	     $url='https://api.weixin.qq.com/customservice/kfaccount/inviteworker?access_token={access_token}';
	    $return=$this->request($url,ijson_encode($post));
	         exi('邀请成功','error');
	}
	//修改客服昵称
	public function custom_update($kf_account,$nickname){
	     $post=array(
	        'kf_account'=>$kf_account, //完整客服帐号，格式为：帐号前缀@公众号微信号
	        'nickname'=>$nickname //客服昵称，最长16个字
	         );
	     $url='https://api.weixin.qq.com/customservice/kfaccount/update?access_token={access_token}';
	     $return=$this->request($url,ijson_encode($post));
	     exi('修改成功','error');
	}
	//上传客服头像
	public function custom_uploadheadimg($kf_account,$source){
	     $post=array(
	         'kf_account'=>$kf_account,
	            'media'=>'@'.ROOT_AT.$source 
	            );
	     $url='https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token={access_token}&kf_account='.$kf_account;
	    $return=$this->request($url,$post);
	    exi('上传成功','error');
	}
    //删除客服账号
    public function custom_del($kf_account){
	     $post=array(
	        'kf_account'=>$kf_account //完整客服帐号，格式为：帐号前缀@公众号微信号
	         );
	     $url='https://api.weixin.qq.com/customservice/kfaccount/del?access_token={access_token}&kf_account='.$kf_account;
	     $this->request($url,$post);
	     exi('删除成功','error');
	}
	//创建客服会话
    public function custom_create($kf_account,$openid){
	     $post=array(
	        'kf_account'=>$kf_account, //完整客服帐号，格式为：帐号前缀@公众号微信号
	        'openid'=>$openid //粉丝openid
	         );
	     $url='https://api.weixin.qq.com/customservice/kfsession/create?access_token={access_token}';
	     $this->request($url,ijson_encode($post));
	}
	//关闭客服会话
    public function custom_close($kf_account,$openid){
	     $post=array(
	        'kf_account'=>$kf_account, //完整客服帐号，格式为：帐号前缀@公众号微信号
	        'openid'=>$openid
	         );
	     $url='https: //api.weixin.qq.com/customservice/kfsession/close?access_token={access_token}';
	     $this->request($url,ijson_encode($post));
	}	
	//获取客户会话状态
    public function custom_session($openid){
	     $post=array(
	        'openid'=>$openid
	         );
	     $url='https://api.weixin.qq.com/customservice/kfsession/getsession?access_token={access_token}&openid='.$openid;
	    $return=$this->request($url,$post);
	     return $return;
	}
	//获取客服会话列表
    public function custom_sessionlist($kf_account){
	     $post=array(
	        'kf_account'=>$kf_account
	         );
	     $url='GET https://api.weixin.qq.com/customservice/kfsession/getsessionlist?access_token={access_token}&kf_account='.$kf_account;
	     $return=$this->request($url,$post);
	      return $return;
	}	
	//获取未接入会话列表
    public function custom_waitcase(){
	     $url='https://api.weixin.qq.com/customservice/kfsession/getwaitcase?access_token={access_token}';
	     $return=$this->request($url);
	     return $return;
	}	
	//获取聊天记录
    public function custom_getmsg($starttime,$endtime,$msgid,$number){
        $post=array(
    	  'starttime'=>$starttime, //起始时间，unix时间戳
          'endtime'=>$endtime, //结束时间，unix时间戳，每次查询时段不能超过24小时
          'msgid'=>$msgid, //消息id顺序从小到大，从1开始
          'number'=>$number //每次获取条数，最多10000条
	         );
	     $url='https://api.weixin.qq.com/customservice/msgrecord/getmsglist?access_token={access_token}';
	    $return=$this->request($url,ijson_encode($post));
	    return $return;
	}			
	//客服输入状态
	public function custom_typing($touser,$command){
	     $post=array(
	        'touser'=>$touser, //对象openid
	        'command'=>$command //发送状态
	         );
	     $url='https://api.weixin.qq.com/cgi-bin/message/custom/typing?access_token=ACCESS_TOKEN&kf_account={access_token}';
	     $return=$this->request($url,ijson_encode($post));
	     return $return;
	     
	}
	public function get_tpl_industry(){
		//先判断行业，如果没有需要的行业，此处设置行业
		$get_url='https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token=ACCESS_TOKEN';
		$res=$this->request($get_url);
		return $res;	
	}
	public function set_tpl_industry($data){
		//设置行业
		$url='https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN';
		$data=ijson_encode($data);
		$res=$this->request($url,$data);
		return $res;	
	}
	public function check_tpl_msg($name,$plugin_name='core',$remark=''){
		$msgtpl_set=uni_setting('msgtpl_set');
		foreach($msgtpl_set as &$mv){
				$tplinfo=pdo_get('core_tpl_template',array('id'=>$mv['tplid']),array('name','plugin_name'));
				if($tplinfo['plugin_name']==$plugin_name && $tplinfo['name']==$name){
					//为了默认显示opentpl==1表示关闭
					if($mv['opentpl']!=1){
						if($mv['send_tplid']){
							$msg=pdo_get('core_account_tpl_template',array('id'=>$mv['send_tplid']),array('first','footer','keywords'));
						}else{
							//默认模板消息推送
							$msg=1;
						}		
						return $msg;
					}else{
						return false;
					}
				}
		}
		return true;
	}
	public function check_tpl_kefumsg($name,$plugin_name='core',$remark=''){
		$msgtpl_set=uni_setting('msgtpl_set');
		foreach($msgtpl_set as &$mv){
				$tplinfo=pdo_get('core_tpl_template',array('id'=>$mv['tplid']),array('name','plugin_name','kefumsg','first','footer','keywords'));
				if($tplinfo['plugin_name']==$plugin_name && $tplinfo['name']==$name){
					//为了默认显示opentpl==1表示关闭
					if($mv['opentpl']!=1){
						if($mv['send_tplid']){
							$msg=pdo_get('core_account_tpl_template',array('id'=>$mv['send_tplid']),array('kefumsg','first','footer','keywords'));
						}else{
							$msg=$tplinfo;
						}		
						return $msg;
					}
				}
		}
		return false;
	}
	public function check_tpl_template($name,$plugin_name='core',$remark=''){
		$msgtpl_set=uni_setting('msgtpl_set');
		foreach($msgtpl_set as &$mv){
				$tplinfo=pdo_get('core_tpl_template',array('id'=>$mv['tplid']),array('name','plugin_name','template_name'));
				if($tplinfo['plugin_name']==$plugin_name && $tplinfo['name']==$name){
					//为了默认显示opentpl==1表示关闭
					if($mv['opentpl']!=1){
						if($mv['send_tplid']){
							$template_name=pdo_getcolumn('core_account_tpl_template',array('id'=>$mv['send_tplid']),'template_name');
						}else{
							$template_name=$tplinfo['template_name'];
						}		
						$template_id=$this->get_tpl_template_id($template_name,$remark);
						return $template_id;
					}
				}
		}
		return false;
	}
	public function get_tpl_template($name,$plugin_name='core'){
		$msgtpl_set=uni_setting('msgtpl_set');
		foreach($msgtpl_set as &$mv){
				$tplinfo=pdo_get('core_tpl_template',array('id'=>$mv['tplid']),array('name','plugin_name','template_name'));
				if($tplinfo['plugin_name']==$plugin_name && $tplinfo['name']==$name){
					//为了默认显示opentpl==1表示关闭
					if($mv['opentpl']!=1){
						if($mv['send_tplid']){
							$tplset=pdo_get('core_account_tpl_template',array('id'=>$mv['send_tplid']));
							return $tplset;
						}else{
							return false;
						}
					}
				}
		}
		return false;
	}
	public function get_tpl_template_id($template_name,$remark='',$isexi=false){
		if($this->wechat['type']!=4){
			if($isexi){
				exi('当前公众号不属于认证服务号，不能发送模板消息！','error');
			}
			return false;
		}
		$this->return_error=true;
		$template=pdo_get('core_account_tpl_template',array('uniacid'=>$_SESSION['uniacid'],'wechat_id'=>$this->wechat['id'],'template_name'=>$template_name),'template_id');
		if(!$template){
			$industrys=$this->get_tpl_industry();
			if(is_error($industrys)){
				if($isexi){
					exi('公众号端模板消息添加失败！获取公众号的行业信息失败！','error');
				}
				return false;
			}
			$need=array('first_class'=>'IT科技','second_class'=>'互联网|电子商务');
			if($industrys['primary_industry']!=$need && $industrys['secondary_industry']!=$need){
				//没有需要的行业，此处设置行业
				$data=array(
					'industry_id1'=>1,//互联网|电子商务
					'industry_id2'=>10,//餐饮 
				);
				$this->set_tpl_industry($data);
			}
			$url='https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token={access_token}';
			$params=array(
				'template_id_short'=>$template_name,
			);
			$res=$this->request($url,ijson_encode($params));
			if(is_error($res)){
				if($isexi){
					exi('公众号端模板消息添加失败！请检查公众号设置！','error');
				}
				return false;
			}
			$template=array(
				'uniacid'=>$_SESSION['uniacid'],
				'wechat_id'=>$this->wechat['id'],
				'template_name'=>$template_name,
				'template_id'=>$res['template_id'],
				'remark'=>$remark,
			);
			pdo_insert('core_account_tpl_template',$template);
		}
		$this->return_error=false;
		return $template['template_id'];
	}
	//发送模版消息
	public function sendTplNotice($openid_mid, $template_id, $postdata, $url = '',$isexi=false) {
		if($this->wechat['type']!=4){
			return true;
		}
		//ID为空，就发送客服消息
		if(!$template_id) {
			if($isexi){
				exi('参数错误,模板标识不能为空','error');
			}else{
				return error( '参数错误,模板标识不能为空');
			}
		}
		if(empty($postdata) || !is_array($postdata)){
			exi( '参数错误,请根据模板规则完善消息内容','error');
		}
		if(empty($openid_mid)) {
			exi('模版消息发送失败,会员ID不能为空','error');
		}
		$data = array();
		if(is_numeric($openid_mid)){
			$openid=$this->get_openid_by_mid($openid_mid);
			if(is_error($openid)){
				return $openid;
			}
			$data['touser'] = $openid;
		}else{
			$data['touser'] = $openid_mid;
		}
		$data['template_id'] = trim($template_id);
		if(is_array($url) && $url['appid']){
			$data['url']='http://weixin.qq.com/download';
			$data['miniprogram']=$url;
		}else{
			$data['url'] = trim($url);
		}
		$data['data'] = $postdata;
		$data = ijson_encode($data);
		$api_url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={access_token}";
		$res=$this->request($api_url,$data,true,false,true,true);
		//发送失败。template_id异常时：
		if($res['errcode']=='40037'){
			$template=pdo_delete('core_account_tpl_template',array('uniacid'=>$_SESSION['uniacid'],'wechat_id'=>$this->wechat['id'],'template_id'=>$template_id));
		}
		if($isexi && $res['errcode']){
			exi('发送模板消息失败！错误代码:'.$res['errcode'].'，错误描述：'.$res['errmsg'],'error');
		}
		return true;
	}
	//被动回复消息
	public function sendBackNotice($message,$return){
		global $_AR;
		$return_types=array(
			'1'=>'text',
			'2'=>'news',
			'3'=>'image',
			'4'=>'voice',
			'5'=>'video',
			'6'=>'music',
			'7'=>'wxcard'
		);
		$return['MsgType']=$return_types[$message['backtype']];
		if($message['backtype']==1){
			$return['Content']=$message['content']['content'];
		}elseif($message['backtype']==2){
			$return['ArticleCount']=count($message['content']);
			foreach($message['content'] as &$c){
				$c['Title']=$c['title'];
				$c['Description']=$c['description'];
				$c['PicUrl']=tomedia($c['picurl']);
				$c['Url']=custom_url($c['url'],true);
				unset($c['title'],$c['description'],$c['picurl'],$c['url']);
			}
			$return['Articles']['item']=$message['content'];
		}elseif($message['backtype']==6){
			$return['Title']=$message['content']['title'];
			$return['Description']=$message['content']['description'];
			$return['MusicUrl']=$message['content']['musicurl'];
		}
		respond($return);
	}
	public function getJssdkConfig(){//获取jssdk参数
		global $_AR;
		if(!$this->wechat['jsticket'] || $this->wechat['jsexpire']<TIMESTAMP){
			$this->getJsApiTicket();
		}
		$nonceStr = random(16);
		$timestamp = TIMESTAMP;
		$url = $_AR['siteurl'];
		$string1 = "jsapi_ticket={$this->wechat['jsticket']}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
		$signature = sha1($string1);
		$config = array(
			"appId"		=> $this->wechat['appid'],
			"nonceStr"	=> $nonceStr,
			"timestamp" => $timestamp,
			"signature" => $signature,
		);
		return $config;
	}
	public function getJsApiTicket(){
		global $_AR;
		$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={access_token}&type=jsapi";
		$result=$this->request($url,'','','',true);
		$record = array();
		$record['jsticket'] = $result['ticket'];
		$record['jsexpire'] = TIMESTAMP + $result['expires_in'] - 200;
		pdo_update('core_account_wechat',$record,array('id'=>$this->wechat['id']));
		$this->wechat['jsticket']=$record['jsticket'];
		return true;
	}
	//将自定义菜单中的链接相对地址转换为绝对地址
	private function check_menu($button){
		if(!is_array($button)){
			return false;
		}
		foreach($button as &$but){
			if($but['sub_button'] && is_array($but['sub_button'])){
				foreach($but['sub_button'] as &$sub){
					if($sub['type']=='view' && substr($sub['url'],0,11)=='./index.php'){
						$sub['url']=get_account_url().'custom'.substr($sub['url'],1);
					}
				}
			}else{
				if($but['type']=='view' && substr($but['url'],0,11)=='./index.php'){
					$but['url']=get_account_url().'custom'.substr($but['url'],1);
				}
			}
		}
		return $button;
	}
	//自定义菜单相关
	public function set_account_menu($id){
		global $_AR;
		$menu=pdo_get('core_account_menus',array('uniacid'=>$_SESSION['uniacid'],'id'=>$id),array('button'));
		if(empty($menu)){
			exi('找不到指定菜单！','error');
		}
		
		$button=json_decode($menu['button'],true);
		
		$button=array_filters($button);
		$button=$this->check_menu($button);
		$button=array('button'=>$button);
		$button=ijson_encode($button);
		
		$url='https://api.weixin.qq.com/cgi-bin/menu/create?access_token={access_token}';
		$this->request($url,$button);
		return true;
	}
	public function set_account_diymenu($id){
		global $_AR;
		$menu=pdo_get('core_account_menus',array('uniacid'=>$_SESSION['uniacid'],'id'=>$id),array('button','matchrule'));
		if(empty($menu)){
			exi('找不到指定菜单！','error');
		}
		$button=json_decode($menu['button'],true);
		$button=array_filters($button);
		$button=$this->check_menu($button);
		$matchrule=json_decode($menu['matchrule'],true);
		$matchrule=array_filters($matchrule);
		$button=array('button'=>$button,'matchrule'=>$matchrule);
		$button=ijson_encode($button);
		$url='https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token={access_token}';
		$this->request($url,$button);
		return true;
	}
	public function del_account_menu($id){
		global $_AR;
		$d=pdo_getcolumn('core_account_menus',array('uniacid'=>$_SESSION['uniacid'],'id'=>$id),'id');
		if(!$d){
			exi('找不到指定菜单！','error');
		}
		
		$url='https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={access_token}';
		$this->request($url);
		return true;
	}
	public function del_account_diymenu($id){
		global $_AR;
		$menuid=pdo_getcolumn('core_account_menus',array('uniacid'=>$_SESSION['uniacid'],'id'=>$id),'menuid');
		if(!$menuid){
			exi('找不到指定菜单！','error');
		}
		$post=array('menuid'=>$menuid);
		$post=json_encode($post);
		$url='https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token={access_token}';
		$this->request($url,$post);
		return true;
	}
	//生成带参数二维码（临时）
	public function barCodeCreateDisposable($barcode) {
		$barcode['expire_seconds'] = empty($barcode['expire_seconds']) ? 2592000 : $barcode['expire_seconds'];
		if (empty($barcode['action_info']['scene']['scene_id']) || empty($barcode['action_name'])) {
			return error('Invalid params');
		}
		$content=$this->request('https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={access_token}',json_encode($barcode));
		return $content;
	}
	//生成带参数二维码（永久）
	public function barCodeCreateFixed($barcode) {
		if($barcode['action_name'] == 'QR_LIMIT_SCENE' && empty($barcode['action_info']['scene']['scene_id'])) {
			return error('1', '场景值错误');
		}
		if($barcode['action_name'] == 'QR_LIMIT_STR_SCENE' && empty($barcode['action_info']['scene']['scene_str'])) {
			return error('1', '场景字符串错误');
		}
		$content=$this->request('https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={access_token}',json_encode($barcode));
		return $content;
	}
	//生成带参数二维码
	public function get_qr($type=1,$plugin='core',$data,$title='未设置',$expire=30,$keyid='',$id='') {
		if($keyid || !$id){
			$qr=pdo_get('core_qr',array('keyid'=>$keyid,'uniacid'=>$_SESSION['uniacid'],'wechat_id'=>$this->wechat['id'],'plugin'=>$plugin));
			if($type==2 && $qr['id']){
				return $qr;
			}
			$id=$qr['id'];
		}
		$types=get_qr_types('id','name');//1表示临时二维码，2表示永久二维码
		if(!$plugin || !$data || !$types[$type]){
			return error('参数错误！');
		}
		$expire=$expire*86400;
		if(!$id){
			$insert=array(
				'uniacid'=>$_SESSION['uniacid'],
				'wechat_id'=>$this->wechat['id'],
				'type'=>$type,
				'plugin'=>$plugin,
				'title'=>$title,
				'data'=>$data,
				'keyid'=>$keyid,
			);
			pdo_insert('core_qr',$insert);
			$id=pdo_insertid();
		}
		$request=array(
			'action_info'=>array('scene'=>array('scene_id'=>$id)),
		);
		$request['action_name']=$types[$type];
		if($type==1){
			$request['expire_seconds']=$expire;
		}
		$content=$this->request('https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={access_token}',json_encode($request));
		if(!$content['ticket']){
			return error('生成二维码失败');
		}
		$image=file_get_contents('https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($content['ticket']));
		$file=cfc('files')->source_save($image,'data','jpg','带参数二维码图片');
		$update=array(
			'file'=>$file,
			'ticket'=>$content['ticket'],
			'createtime'=>TIMESTAMP,
			'url'=>$content['url']
		);
		if($type==1){
			$update['expire']=TIMESTAMP+$content['expire_seconds']-100;
		}
		pdo_update('core_qr',$update,array('id'=>$id));
		$result=array(
			'id'=>$id,
			'ticket'=>$content['ticket'],
			'url'=>$content['url'],
			'file'=>$file,
		);
		return $result;
	}
	
	public function url_short($url,$return_error=false){
		$api='https://api.weixin.qq.com/cgi-bin/shorturl?access_token={access_token}';
		$post=array(
			'action'=>'long2short',
			'long_url'=>$url
		);
		$result=$this->request($api,$post,'','',$return_error);
		return $result['short_url'];
	}
	public function getsaletask_mids($mass,$post=array(),$tplid=''){
		$saletask_set=$mass['saletask_set']?json_decode($mass['saletask_set'],true):array();
		$_SESSION['saletask_page'.$mass['id']]=$_SESSION['saletask_page'.$mass['id']]?:1;
		$mids=$this->midslist_mass($saletask_set,$_SESSION['saletask_page'.$mass['id']],$mass['saletask_type'],$mass['id'],$post,$tplid);
		return $mids;
	}
	//会员列表群发
	public function midslist_mass($saletask_set,$page=1,$saletask_type=1,$massid=0,$content=array(),$tplid=false) {
		//显示统计数据
		$daytime = mktime(0,0,0,date('m'),date('d'),date('Y'));
		$times=$saletask_set['timesdays']*24*3600;
		$params=array('uniacid'=>$_SESSION['uniacid'],'is_virtual'=>0);
		if($saletask_type==2){//近3月新会员
			$params['createtime >']=TIMESTAMP-90*24*3600;
		}elseif($saletask_type==9){//指定手机
			$params['mobile']=$saletask_set['mobile'];
		}elseif($saletask_type==13){//付费会员特价体验
			$params['level_id']=0;
		}
		$pindex = max(1, intval($page));
		$psize = 100;
		$list=pdo_getslice('core_members',array('uniacid'=>$_SESSION['uniacid']),array($pindex,$psize),$total,array('id','birth','createtime'),'','id desc');
		$params=array('uniacid'=>$_SESSION['uniacid']);
		foreach($list as $k=>$item){
			$params['mid']=$item['id'];
			if($saletask_type==1){//自定义人群			
				if($saletask_set['datatype']==1){//订单数据
					if($saletask_set['isjiaoyu']==1){//没订单
						if($times){
							$params['createtime >']=TIMESTAMP-$times;
						}
						$count=pdo_count('core_paylog',$params,'id');
						if($count){
							unset($list[$k]);
							continue;
						}
					}elseif($saletask_set['isjiaoyu']==2){//有订单未支付
						$params['status']=0;
						if($times){
							$params['createtime >']=TIMESTAMP-$times;
						}
						$count=pdo_count('core_paylog',$params,'id');
						if(!$count){
							unset($list[$k]);
							continue;
						}
					}else{//已消费
						$params['status']=1;
						if($times){
							$params['createtime >']=TIMESTAMP-$times;
						}
						$count=pdo_count('core_paylog',$params,'id');
						if(!$count){
							unset($list[$k]);
							continue;
						}
					}
				}elseif($saletask_set['datatype']==2){//粉丝数据
					
				}elseif($saletask_set['datatype']==3){//活动日
					if($saletask_set['ertype']==1){//生日
						$item['birth']=$item['birth']?json_decode($item['birth'],true):array();
						$m=date('m');
						$d=date('d');
						if(!$item['birth'] || $item['birth']['month']!=$m || $item['birth']['day']!=$d){
							unset($list[$k]);
							continue;
						}
					}elseif($saletask_set['ertype']==1){//会员日
						$mm=date('m',$item['createtime']);
						$md=date('d',$item['createtime']);
						$m=date('m');
						$d=date('d');
						if($mm!=$m || $md!=$d){
							unset($list[$k]);
							continue;
						}
					}elseif($saletask_set['ertype']==1){//节日
						
					}
				}else{
					exi('自定义人群,没有任何参数或数据类型错误，无法推送信息！','error');
				}
			}elseif($saletask_type==2){//未消费新增用户
				$params['status']=1;
				$count=pdo_count('core_paylog',$params,'id');
				if($count){
					unset($list[$k]);
					continue;
				}
			}elseif($saletask_type==3){//兴趣人群转化
				$params['status']=0;
				$params['createtime >']=TIMESTAMP-7*24*3600;
				$count=pdo_count('core_paylog',$params,'id');
				if(!$count){
					unset($list[$k]);
					continue;
				}
				
			}elseif($saletask_type==4){//互动粉丝用户
				
			}elseif($saletask_type==5){//需重点召回客户
				$params['createtime >']=TIMESTAMP-90*24*3600;
				$count=pdo_count('core_paylog',$params,'id');
				if($count){
					unset($list[$k]);
					continue;
				}
			}elseif($saletask_type==6){//需重点发展客户
				$params['status']=1;
				$params['createtime >']=TIMESTAMP-30*24*3600;
				$count=pdo_count('core_paylog',$params,'id');
				if(!$count){
					unset($list[$k]);
					continue;
				}
				
			}elseif($saletask_type==7){//需重点活跃客户
				$params['createtime >']=TIMESTAMP-30*24*3600;
				$count=pdo_count('core_paylog',$params,'id');
				if($count){
					unset($list[$k]);
					continue;
				}
			}elseif($saletask_type==8){//需刺激消费客户
				$params['createtime >']=TIMESTAMP-30*24*3600;
				$count=pdo_count('core_paylog',$params,'id');
				if(!$count || $count>10){
					unset($list[$k]);
					continue;
				}
			}elseif($saletask_type==9){//指定手机客户
				
			}elseif($saletask_type==10){//会员日营销
				$mm=date('m',$item['createtime']);
				$md=date('d',$item['createtime']);
				$m=date('m');
				$d=date('d');
				if($mm!=$m || $md!=$d){
							unset($list[$k]);
							continue;
				}
			}elseif($saletask_type==11){//生日营销
				$item['birth']=$item['birth']?json_decode($item['birth'],true):array();
				$m=date('m');
				$d=date('d');
				if(!$item['birth'] || $item['birth']['month']!=$m || $item['birth']['day']!=$d){
							unset($list[$k]);
							continue;
				}
			}elseif($saletask_type==12){//节日营销
				
			}elseif($saletask_type==13){//付费会员特价体验
				
			}
			$openid=pdo_getcolumn('core_fans',array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'mid'=>$item['id']),'openid');
			if($openid){
				if($tplid){
					$this->sendTplNotice($openid, $tplid, $content, '');
				}else{
					$this->sendCustomNotice($content,$openid);
				}
			}
		}
		if($total>10000 && $page*10000<$total){
			//粉丝数超过10000且尚未拉取完，继续拉取
			$page++;
			$_SESSION['saletask_page'.$massid]=$page;
			return $this->midslist_mass($params,$page,$result['next_openid']);
		}
	}
	//错误码
	public function error_code($code, $errmsg = '未知错误') {//获取错误详情
		global $_AR;
		$errors = array(
			'-1' => '系统繁忙',
			'0' => '请求成功',
			'40001' => '获取access_token时AppSecret错误，或者access_token无效',
			'40002' => '不合法的凭证类型',
			'40003' => '不合法的OpenID',
			'40004' => '不合法的媒体文件类型',
			'40005' => '不合法的文件类型',
			'40006' => '不合法的文件大小',
			'40007' => '不合法的媒体文件id',
			'40008' => '不合法的消息类型',
			'40009' => '不合法的图片文件大小',
			'40010' => '不合法的语音文件大小',
			'40011' => '不合法的视频文件大小',
			'40012' => '不合法的缩略图文件大小',
			'40013' => '不合法的APPID',
			'40014' => '不合法的access_token',
			'40015' => '不合法的菜单类型',
			'40016' => '不合法的按钮个数',
			'40017' => '不合法的按钮个数',
			'40018' => '不合法的按钮名字长度',
			'40019' => '不合法的按钮KEY长度',
			'40020' => '不合法的按钮URL长度',
			'40021' => '不合法的菜单版本号',
			'40022' => '不合法的子菜单级数',
			'40023' => '不合法的子菜单按钮个数',
			'40024' => '不合法的子菜单按钮类型',
			'40025' => '不合法的子菜单按钮名字长度',
			'40026' => '不合法的子菜单按钮KEY长度',
			'40027' => '不合法的子菜单按钮URL长度',
			'40028' => '不合法的自定义菜单使用用户',
			'40029' => '不合法的oauth_code',
			'40030' => '不合法的refresh_token',
			'40031' => '不合法的openid列表',
			'40032' => '不合法的openid列表长度',
			'40033' => '不合法的请求字符，不能包含\uxxxx格式的字符',
			'40035' => '不合法的参数',
			'40038' => '不合法的请求格式',
			'40039' => '不合法的URL长度',
			'40050' => '不合法的分组id',
			'40051' => '分组名字不合法',
			'41001' => '缺少access_token参数',
			'41002' => '缺少appid参数',
			'41003' => '缺少refresh_token参数',
			'41004' => '缺少secret参数',
			'41005' => '缺少多媒体文件数据',
			'41006' => '缺少media_id参数',
			'41007' => '缺少子菜单数据',
			'41008' => '缺少oauth code',
			'41009' => '缺少openid',
			'42001' => 'access_token超时',
			'42002' => 'refresh_token超时',
			'42003' => 'oauth_code超时',
			'43001' => '需要GET请求',
			'43002' => '需要POST请求',
			'43003' => '需要HTTPS请求',
			'43004' => '需要接收者关注',
			'43005' => '需要好友关系',
			'44001' => '多媒体文件为空',
			'44002' => 'POST的数据包为空',
			'44003' => '图文消息内容为空',
			'44004' => '文本消息内容为空',
			'45001' => '多媒体文件大小超过限制',
			'45002' => '消息内容超过限制',
			'45003' => '标题字段超过限制',
			'45004' => '描述字段超过限制',
			'45005' => '链接字段超过限制',
			'45006' => '图片链接字段超过限制',
			'45007' => '语音播放时间超过限制',
			'45008' => '图文消息超过限制',
			'45009' => '接口调用超过限制',
			'45010' => '创建菜单个数超过限制',
			'45015' => '回复时间超过限制',
			'45016' => '系统分组，不允许修改',
			'45017' => '分组名字过长',
			'45018' => '分组数量超过上限',
			'45030' => '该cardid无接口权',
			'45056' => '创建的标签数过多，请注意不能超过100个',
			'45057' => '该标签下粉丝数超过10w，不允许直接删除',
			'45058' => '不能修改0/1/2这三个系统默认保留的标签',
			'45059' => '有粉丝身上的标签数已经超过限制',
			'45157' => '标签名非法，请注意不能和其他标签重名',
			'45158' => '标签名长度超过30个字节',
			'45159' => '非法的标签',
			'46001' => '不存在媒体数据',
			'46002' => '不存在的菜单版本',
			'46003' => '不存在的菜单数据',
			'46004' => '不存在的用户',
			'47001' => '解析JSON/XML内容错误',
			'48001' => 'api 功能未授权，请确认公众号已获得该接口，可以在公众平台官网 - 开发者中心页中查看接口权限',
			'50001' => '用户未授权该api',
			'40070' => '基本信息baseinfo中填写的库存信息SKU不合法。',
			'41011' => '必填字段不完整或不合法，参考相应接口。',
			'40056' => '无效code，请确认code长度在20个字符以内，且处于非异常状态（转赠、删除）。',
			'43009' => '无自定义SN权限，请参考开发者必读中的流程开通权限。',
			'43010' => '无储值权限,请参考开发者必读中的流程开通权限。',
			'43011' => '无积分权限,请参考开发者必读中的流程开通权限。',
			'40078' => '无效卡券，未通过审核，已被置为失效。',
			'40079' => '基本信息base_info中填写的date_info不合法或核销卡券未到生效时间。',
			'45021' => '文本字段超过长度限制，请参考相应字段说明。',
			'40080' => '卡券扩展信息cardext不合法。',
			'40097' => '基本信息base_info中填写的参数不合法。',
			'49004' => '签名错误。',
			'43012' => '无自定义cell跳转外链权限，请参考开发者必读中的申请流程开通权限。',
			'40099' => '该code已被核销。',
			'61005' => '缺少接入平台关键数据，等待微信开放平台推送数据，请十分钟后再试或是检查“授权事件接收URL”是否写错（index.php?c=account&amp;a=auth&amp;do=ticket地址中的&amp;符号容易被替换成&amp;amp;）',
			'61023' => '请重新授权接入该公众号',
			'85005'=>'小程序未关联公众号，无法通过自定义菜单跳转！',
			'40164'=>'服务器IP不在白名单导致接口请求失败！请前往公众平台——开发——基本配置——公众号开发信息——IP白名单处设置',
		);
		$code = strval($code);
		if($errors[$code]) {
			return $errors[$code];
		} else {
			return $errmsg;
		}
	}
}